import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, Lasso
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
from sklearn.preprocessing import PolynomialFeatures
from sklearn.ensemble import RandomForestRegressor
import numpy as np

# 加载数据集
file_path = r"C:\Users\HYHPlayer_MHS\Downloads\house-info.csv"
df = pd.read_csv(file_path, encoding='utf-8')


# 设置选项以选择未来行为
pd.set_option('future.no_silent_downcasting', True)

# 删除网址
df.drop(columns=['网址'], inplace=True)

# 查看数据总体情况
print(f"样本量共有 {df.shape[0]} 个")

# 将 "暂无" 和 "NaN" 替换为 np.nan
df.replace(['暂无', 'NaN', '无', 'nan'], np.nan, inplace=True)

# 计算每列的缺失值数量和缺失值比例，并按降序排序
missing_values = df.isnull().sum().sort_values(ascending=False)
total_samples = df.shape[0]
missing_percentage = (missing_values / total_samples) * 100

# 创建包含缺失值数量和缺失值比例的DataFrame
missing_data = pd.DataFrame({'缺失值数量': missing_values, '缺失值比例': missing_percentage})

# 打印缺失值情况
print("缺失值情况（按缺失值比例排序）:")
print(missing_data)

# 删除车位数量
df.drop(columns=['车位数量'], inplace=True)

#将车库数量列的所有缺失值改为0
df.fillna({'车库数量': 0}, inplace=True)

#删除建筑形式
df.drop(columns=['建筑形式'], inplace=True)
print('hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh')
# 删除包含缺失值的行
df.dropna(inplace=True)
print('hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh')
# 打印处理缺失值后的数据量
print(f"删除缺失值后的数据样本量: {df.shape[0]}")

# 查看数据类型
data_types = df.dtypes
print("数据类型:")
print(data_types)

# 唯一标签值
print(df['朝向'].unique())
print(df['楼层'].unique())
print(df['装修程度'].unique())
print(df['产权性质'].unique())
print(df['住宅类别'].unique())
print(df['建筑结构'].unique())
print(df['地区'].unique())
print(df['建筑年代'].unique())
print(df['有无电梯'].unique())
print(df['车库数量'].unique())

# 处理总价
df['建筑年代'] = df['建筑年代'].str.extract(r'(\d{4})')[0]
df = df.dropna(subset=['总价'])
print(f"处理总价后的数据量: {df.shape[0]}")



# 处理建筑面积
df['建筑面积'] = df['建筑面积'].astype(str).str.replace('平米', '')
df['建筑面积'] = pd.to_numeric(df['建筑面积'], errors='coerce')
df = df.dropna(subset=['建筑面积'])
print(f"处理建筑面积后的数据量: {df.shape[0]}")

# 分解户型
def apart_room(x):
    try:
        room = x.split('室')[0]
        return int(room)
    except:
        return None

def apart_hall(x):
    try:
        hall = x.split('厅')[0].split('室')[1]
        return int(hall)
    except:
        return None

def apart_wc(x):
    try:
        wc = x.split('卫')[0].split('厅')[1]
        return int(wc)
    except:
        return None

df['室'] = df['户型'].map(apart_room)
df['厅'] = df['户型'].map(apart_hall)
df['卫'] = df['户型'].map(apart_wc)

# 删除无法解析户型信息的行
df = df.dropna(subset=['室', '厅', '卫'])
print(f"处理户型信息后的数据量: {df.shape[0]}")

# 删除'户型', '单价', '楼层', '挂牌时间'
df.drop(columns=['户型', '单价', '楼层', '挂牌时间'], inplace=True)
print(f"更新处理户型信息后的数据量: {df.shape[0]}")

'''
# 编码 - 有序多分类
map1 = {'南': 5, '南北': 6, '北': 1, '西南': 10, '东西': 4, '东': 2, '东北': 8, '东南': 9, '西': 3, '西北': 7, '东南北': 3, '西南北': 2, '东西北': 4, '东西南': 3, '东西南北': 3}
df['朝向'] = df['朝向'].map(map1)

map2 = {'毛坯': 1, '简装修': 2, '精装修': 3, '中装修': 4, '豪华装修': 5}
df['装修程度'] = df['装修程度'].map(map2)

map3 = {'有 ': 1, '无 ': 0}
df['有无电梯'] = df['有无电梯'].map(map3)

map4 = {'商品房': 6, '个人产权': 5, '单位产权': 7, '70年': 4, '经济适用房': 2, '成本价房改房': 3, '限价房': 8, '使用权': 1}
df['产权性质'] = df['产权性质'].map(map4)

map5 = {'普通住宅': 4, '四合院': 3, '公寓': 1, '商业办公类': 2, '酒店式公寓': 5}
df['住宅类别'] = df['住宅类别'].map(map5)

map6 = {'平层': 4, '开间': 2, '跃层': 5, '错层': 1, '复式': 3}
df['建筑结构'] = df['建筑结构'].map(map6)

map7 = {'板楼': 4, '钢混': 5, '塔板结合': 3, '平房': 6, '砖混': 1, '塔楼': 7, '砖楼': 2}
df['建筑形式'] = df['建筑形式'].map(map7)

map8 = {'朝阳': 6, '东城': 5, '西城': 4, '吕平': 3, '顺义': 2, '通州': 1, '海淀': 3, '密云': 3, '石景山': 3, '房山': 3, '燕郊': 3, '丰台': 3, '门头沟': 3, '大兴': 3, '怀柔': 3, '北京周边': 3}
df['地区'] = df['地区'].map(map8)

# 去除“建筑年代”中的非数字字符，并转换为int类型
df['建筑年代'] = df['建筑年代'].astype(str).str.extract(r'(\d{4})', expand=False)
df['建筑年代'] = pd.to_numeric(df['建筑年代'], errors='coerce')
df = df.dropna(subset=['建筑年代'])
df['建筑年代'] = df['建筑年代'].astype(int)


# 删除超过2019年的房子，年代转变为房龄
df.drop(index=df[df['建筑年代'] > 2019].index, inplace=True)
df['房龄'] = 2020 - df['建筑年代']
df.drop(columns=['建筑年代'], inplace=True)

# 再次删除任何包含NaN的行
df = df.dropna()
print(f"最终处理后的数据量: {df.shape[0]}")

# 显示处理后的数据集
print("处理后的数据集:")
print(df.head())

# 统计分析：计算各户型的数量和平均总价
house_type_grouped_data = df.groupby(['室', '厅', '卫']).agg(
    平均总价=('总价', 'mean'),
    数量=('总价', 'size')
).reset_index()

# 显示不同户型的统计结果
print("\n不同户型的统计结果:")
print(house_type_grouped_data)
print('hhhhhhhhhhhhhhhhhhhhhh')
#检查数据类型和内容
print(df.info())
print(df.head())
print('hhhhhhhhhhhhhhhhhhhhhh')

# 准备训练和测试数据
X = df.drop(columns=['总价'])
y = df['总价']
x_train, x_test, y_train, y_test = train_test_split(X, y, random_state=33)

# 多项式特征转换
poly = PolynomialFeatures(degree=2)
x_train = poly.fit_transform(x_train.values)
x_test = poly.fit_transform(x_test)

# 套索回归
la = Lasso(alpha=0.1, max_iter=100000)
la.fit(x_train, y_train)
print(f'训练集得分：{round(la.score(x_train, y_train), 2)}')
print(f'测试集得分：{round(la.score(x_test, y_test), 2)}')

# 随机森林
rf = RandomForestRegressor()

rf.fit(x_train, y_train)
print(f'训练集得分：{round(rf.score(x_train, y_train), 2)}')
print(f'测试集得分：{round(rf.score(x_train, y_train), 2)}')
'''